<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>

</body>
<script>
    // 递归的三个特点：
    //     1.函数自己调用自己  （标志性的特点）
    //     2.一般情况下有参数
    //     3.一般情况下有return、
    // 【注】递归可以解决循环能干的所有的事

    // 案例：计算1~n的和
    // function add(n){
    //     var sum=0;
    //     for(i=1;i<=n;i++){
    //         sum+=i;
    //     }
    //     return sum;
    // }
    // console.log(add(100))

    // 递归的方法：
    //     1、首先去找临界值，即无需计算，获得的值
    //     2、找这一次和上一次的关系
    //     3、假设当前函数已经可以使用，调用自身计算上一次

    // 用递归法实现计算1~n的和
    function add(n) {
        if (n == 1) {
            return 1;
        }
        // add(100)=add(99)+100;
        // add(n)=add(n-1)+n
        return add(n - 1) + n;
    }
    console.log(add(100))

    // 递归：一瞬间开大量的内存，然后一瞬间释放掉
    // add(100)=add(99)+100;
    // add(99)=add(98)+99;
    // add(98)=add(97)+98;
    // add(97)=add(96)+97;
    // ....
    // add(3)=add(2)+3;
    // add(2)=add(1)+2;
    // add(1)=1;

    // 利用递归实现n的阶乘
    // f(5)=5*f(4)

    function fn(n) {
        if (n == 1) {
            return 1;
        }
        return n * fn(n - 1);
    }
    console.log(fn(5));


    // 利用递归求斐波那契数列（1，1，2，3，5，8，13，21，34，55，89...）
    // 临界值 f(1)=1,f(2)=1;
    // 上下之间的关系
    // f(n)=f(n-1)+f(n-2)


    function sum(n) {
        if (n == 1 || n == 2) {
            return 1;
        }
        return sum(n-1)+sum(n-2);
    }
    console.log(sum(8));



    // 编写一个函数，输入n为偶数时，调用函数求1/2+1/4+...+1/n,当输入n为奇数时，调用函数求1+1/3+...+1/n    循环和递归
                    // 1/2+1/4+...+1/n,        1/2n
                    // 1/2 1/4 1/6 1/8

    function aaa(n){
        var s=0
        if(n%2==0){
            return s+=aaa(1/2*n)
        }else{
            if(n=1){
                return 1;
            }
            return s+=aaa(1/2*n+1)
        }
    }
    console.log(aaa(4))
</script>

</html>